package dcc.shannonfano;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;

/**
 * The Class BitReader. File Bit Reader - Read Files BitWise
 */
public class BitReader {

	/** The file name. */
	private String fileName;

	/** The input file. */
	private File inputFile;
	
	/** The fin. */
	private FileInputStream fin;
	
	/** The in. */
	private BufferedInputStream in;
	
	/** The current byte. */
	private String currentByte;

	/**
	 * Instantiates a new bit reader.
	 *
	 * @throws Exception the exception
	 */
	public BitReader() throws Exception {
		try {
			fileName = "";
			// loadFile(fileName);
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * Instantiates a new bit reader.
	 *
	 * @param txt the txt
	 * @throws Exception the exception
	 */
	public BitReader(String txt) throws Exception {
		try {
			fileName = txt;
			loadFile(fileName);
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * Load file.
	 *
	 * @param txt the txt
	 * @return true, if successful
	 * @throws Exception the exception
	 */
	public boolean loadFile(String txt) throws Exception {
		fileName = txt;

		try {
			inputFile = new File(fileName);
			fin = new FileInputStream(inputFile);
			in = new BufferedInputStream(fin);
			currentByte = "";
			return true;

		} catch (Exception e) {
			throw e;
		}

		// return true;
	}

	/**
	 * Left pad8.
	 *
	 * @param txt the txt
	 * @return the string
	 */
	String leftPad8(String txt) {
		while (txt.length() < 8)
			txt = "0" + txt;
		return txt;
	}

	/**
	 * Right pad8.
	 *
	 * @param txt the txt
	 * @return the string
	 */
	String rightPad8(String txt) {
		while (txt.length() < 8)
			txt += "0";
		return txt;
	}

	/**
	 * Gets the bit.
	 *
	 * @return the bit
	 * @throws Exception the exception
	 */
	public String getBit() throws Exception {
		try {
			if (currentByte.length() == 0 && in.available() >= 1) {
				int k = in.read();

				currentByte = Integer.toString(k, 2);
				currentByte = leftPad8(currentByte);
			}
			if (currentByte.length() > 0) {
				String ret = currentByte.substring(0, 1);
				currentByte = currentByte.substring(1);
				return ret;
			}
			return "";
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Gets the bits.
	 *
	 * @param n the n
	 * @return the bits
	 * @throws Exception the exception
	 */
	public String getBits(int n) throws Exception {
		try {
			String ret = "";
			for (int i = 0; i < n; i++) {
				ret += getBit();
			}
			return ret;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Gets the bytes.
	 *
	 * @param n the n
	 * @return the bytes
	 * @throws Exception the exception
	 */
	public String getBytes(int n) throws Exception {
		try {
			String ret = "", temp;
			for (int i = 0; i < n; i++) {
				temp = getBits(8);
				char k = (char) Integer.parseInt(temp, 2);
				ret += k;
			}
			return ret;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * Eof.
	 *
	 * @return true, if successful
	 * @throws Exception the exception
	 */
	public boolean eof() throws Exception {
		try {

			return (in.available() == 0);
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * Available.
	 *
	 * @return the long
	 * @throws Exception the exception
	 */
	public long available() throws Exception {
		try {
			return in.available();
		} catch (Exception e) {
			throw e;
		}

	}

	/**
	 * Close file.
	 *
	 * @throws Exception the exception
	 */
	public void closeFile() throws Exception {
		try {
			in.close();
		} catch (Exception e) {
			throw e;
		}

	}

}
